package com.lrj.mysecurity.security;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class DataBaseWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /**
         * 登录只是认证用户身份，用户访问资源需要用户有对应的权限
         * 注意：antMatchers不能写在anyRequest方法后面，否则报以下错误
         * Can't configure antMatchers after anyRequest
         */

        /**
         * 需要有admin角色才能访问
         */
//        http
//                .authorizeRequests()
//                .antMatchers("/admin/**")
//                .hasRole("admin");

        /**
         * 需要有读取用户信息的权限才能访问
         */
//        http
//                .authorizeRequests()
//                .antMatchers("/user/{id}")
//                .hasAuthority("user.read");

        /**
         * 配置h2前端查看器
         */
        http
                .authorizeRequests()
                .antMatchers("/h2/**")
                .permitAll()
                .and()
                //Spring Security 默认页面不允许 iframe （不安全），会在响应头返回：X-Frame-Options:DENY
                //解决方法：允许同源使用 iframe
                .headers()
                .frameOptions()
                .sameOrigin();

        /**
         * 个人理解
         * http.authorizeRequests().anyRequest().authenticated()
         * 表示所有的请求都需要认证
         */
        http
                .authorizeRequests()
                .anyRequest()
                .authenticated();

        /**
         * http.formLogin().loginPage("/login.html").loginProcessingUrl("/login")
         * 自定义登录页，并且设置登陆处理url为/login但有问题，上面已经设置了所有请求都需要认证
         * 所以/login.html请求会重定向到/login.html，一直重复，所以出现“重定向的次数过多”错误
         * 解决方法是将登陆页设置为免认证，即：
         * http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll()
         *
         * 接下来会发现一个问题，不管登陆成功还是失败，出现的页面永远是登录页
         * 这是因为Spring Security默认是开启CSRF的
         * 至于CSRF是什么，具体还不了解
         * 可以通过关掉CSRF来解决问题（当然还有其他方法）
         */
        http
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .httpBasic();

        /**
         * 关闭csrf
         */
        http
                .csrf()
                .disable();

        /**
         * 解决跨域问题（光是这一步还不够，还需要创建一个类实现WebMvcConfigurer，并重写addCorsMappings方法）
         */
        http
                .cors();

        /**
         * 以上三行代码（虽然分了很多行，但把回车符去掉就三行）
         * 是可以写成一行的
         * 例如http.authorizeRequests().anyRequest().authenticated()后面可以加上.and()
         * 然后再and()后加上.formLogin()...
         * 效果一样的
         */

    }

}
